/* BSQReader.java 
 * Created on September 20, 2004, 7:23 PM
 */

package edu.temple.GUS.MMA.io;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

import edu.temple.GUS.MMA.DataTypes.MMAGrid;
import edu.temple.GUS.MMA.DataTypes.MMAHyperCube;
import edu.temple.GUS.MMA.DataTypes.MMASpaceCube;
import edu.temple.GUS.MMA.DataTypes.MMATimeCube;
import edu.temple.GUS.MMA.DataTypes.MMATimeSeries;

/**
 * 
 * @author rkhanna
 */
public class ArcGridReader {
	private static String cubetype = "";
	private static int countrow = 0;
	private static int X;
	private static int Y;
	private static int Z;
	private static int T;
	private static int xll;
	private static int yll;
	private static int noData;
	private static int xResolution;
	private static int yResolution;
	private static int zResolution;
	private static int tResolution;
	private static int tempint = 0;
	private static String path = "";
	private static String headerfile = "";

	/** Creates a new instance of BSQReader */

	public static void main(String[] args) {
		try {
			// V:\ToyData\ToyGrid
			MMAHyperCube hcobj = BSQReader
					.readHyperCube(
							"V:\\Todd\\hypercube_relative_humidity\\hypercube_relative_humidity\\",
							"hypercube.hdr");
			// MMAHyperCube hcobj =
			// BSQReader.readHyperCube("V:\\TestData\\MMA_input\\hypercube_input\\",
			// "hypercube.hdr");
			// BSQWriter.writeHyperCube(hcobj, "V:\\temp\\");

			// V:\TestData\MMA_input\hypercube_input
			/*
			 * MMASpaceCube tc =
			 * BSQReader.readSpaceCube("V:\\TestData\\MMA_input\\spacecube_input\\"
			 * , "spacecube.hdr"); LocalRollUpMeanZ addobj = new
			 * LocalRollUpMeanZ(); MMAGrid resultobj = addobj.execute(tc);
			 * BSQWriter.writeGrid(resultobj,
			 * "V:\\testresult\\LocalRollup\\MeanZ\\");
			 */
		} catch (Exception e) {
			System.out.println("Exception caught");
		}
	}

	public static boolean validate(String gridtype, String path, String filename) {
		String cubetype = "";
		String data = "";
		headerfile = filename;
		countrow = 0;

		try {
			File f = new File(path + headerfile);
			FileInputStream fis = new FileInputStream(f);
			BufferedInputStream bis = new BufferedInputStream(fis);
			BufferedReader myInput = new BufferedReader(new InputStreamReader(
					bis));

			bigloop: while ((data = myInput.readLine()) != null) {
				countrow++;
				// convert every row in header file except 1st to int
				if ((countrow != 1) && (countrow < 11)) {
					tempint = Integer.parseInt(data);
				}
				// capture X, Y, Z & T coordinates & resolutions
				if (countrow == 2) {
					X = tempint;
				}
				if (countrow == 3) {
					Y = tempint;
				}
				if (countrow == 4) {
					Z = tempint;
				}
				if (countrow == 5) {
					T = tempint;
				}
				if (countrow == 6) {
					xResolution = tempint;
				}
				if (countrow == 7) {
					yResolution = tempint;
				}
				if (countrow == 8) {
					zResolution = tempint;
				}
				if (countrow == 9) {
					tResolution = tempint;
				}
				if (countrow == 10) {
					noData = tempint;
				}
				if (countrow == 11) {
					xll = tempint;
				}
				if (countrow == 12) {
					yll = tempint;
				}

				if (gridtype.equals("grid")) {
					if (((countrow == 4) || (countrow == 5) || (countrow == 8) || (countrow == 9))
							&& (tempint != 0)) {
						System.out
								.println("Gird's Z, T, Resolution of Z, Resolution of T has to be zero");
						return true;
					}
				}

				if (gridtype.equals("timecube")) {
					if (((countrow == 4) || (countrow == 8)) && (tempint != 0)) {
						System.out
								.println("Timecube's Z & Resolution of Z has to be zero");
						return true;
					}
				}

				if (gridtype.equals("spacecube")) {
					if (((countrow == 5) || (countrow == 9)) && (tempint != 0)) {
						System.out
								.println("Spacecube's t & Resolution of t has to be zero");
						return true;
					}
				}
			}// end of while
		} catch (IOException e) {
			// catch io errors from FileInputStream or readLine()
			System.out.println("Uh oh, got an IOException error!"
					+ e.getMessage());
		}
		return false;
	}

	public static MMAGrid readGrid(String path, String filename) {
		System.out.println("Readgrid called");
		System.out.println("1");
		boolean flag = validate("grid", path, filename);
		System.out.println("2");
		if (flag) {
			return null;
		}
		float arr[][] = new float[Y][X];
		String thisLine = "";
		int i = 0;
		int j = 0;
		String file1 = new String(path + "1.dat");
		try {
			FileInputStream fis = new FileInputStream(file1);
			BufferedInputStream bis = new BufferedInputStream(fis);
			BufferedReader myInput = new BufferedReader(new InputStreamReader(
					bis));
			while ((thisLine = myInput.readLine()) != null) {
				// scan it line by line
				System.out.println(thisLine);
				StringTokenizer st = new StringTokenizer(thisLine);
				i = 0;
				while (st.hasMoreTokens()) {
					arr[j][i] = Float.valueOf(st.nextToken()).floatValue();
					// System.out.println(x + "::::" + y + "::" + arr[x][y]);
					i++;
				}
				j++;
			}// end of while
		} catch (Exception e) {
			System.out.println("Exception thrown from readGrid" + e);
		}
		MMAGrid gridobj = new MMAGrid();
		gridobj.putX(X);
		gridobj.putY(Y);
		gridobj.putXResolution(xResolution);
		gridobj.putYResolution(yResolution);
		gridobj.putNoData(noData);
		gridobj.putData(arr);
		gridobj.putXLL(xll);
		gridobj.putYLL(yll);
		System.out.println("XX" + X);
		System.out.println("YY" + Y);

		for (j = 0; i < X; i++) {
			for (i = 0; j < Y; j++) {
				System.out.print(arr[j][i]);
			}
		}
		// System.out.println("i  ::"+"j  ::"+arr[i][j]);
		return gridobj;
	}

	public static MMATimeCube readTimeCube(String path, String filename) {
		validate("timecube", path, filename);
		System.out.println("Initialise Timecube array called" + X + ":::" + Y
				+ ":::" + T);
		float arr[][][] = new float[T][Y][X];
		String thisLine = "";
		int i = 0;
		int j = 0;
		int openfile = 0;
		for (int k = 0; k < T; k++) {
			openfile = k + 1;
			String file1 = new String(path + openfile + ".dat");
			try {
				FileInputStream fis = new FileInputStream(file1);
				BufferedInputStream bis = new BufferedInputStream(fis);
				BufferedReader myInput = new BufferedReader(
						new InputStreamReader(bis));
				while ((thisLine = myInput.readLine()) != null) {
					// scan it line by line
					System.out.print(thisLine);
					StringTokenizer st = new StringTokenizer(thisLine);
					i = 0;
					while (st.hasMoreTokens()) {
						arr[k][j][i] = Float.valueOf(st.nextToken())
								.floatValue();
						// System.out.println(k+ "::" +j + "::" + i + "::" +
						// arr[k][j][i]);
						i++;
					}
					j++;
				}// end of while
				j = 0;
				fis.close();
				bis.close();
				myInput.close();
			} catch (Exception e) {
				System.out.println("Exception thrown from initialiseGridArray"
						+ e);
			}

			System.out.println("XX" + X);
			System.out.println("YY" + Y);
			System.out.println("ZZ" + T);
		}// end of for

		MMATimeCube timecubeobj = new MMATimeCube();
		timecubeobj.putX(X);
		timecubeobj.putY(Y);
		timecubeobj.putT(T);
		timecubeobj.putXResolution(xResolution);
		timecubeobj.putYResolution(yResolution);
		timecubeobj.putTResolution(tResolution);
		timecubeobj.putNoData(noData);
		timecubeobj.putData(arr);
		timecubeobj.putXLL(xll);
		timecubeobj.putYLL(yll);

		for (int k = 0; k < T; k++) {
			for (j = 0; j < Y; j++) {
				for (i = 0; i < X; i++) {
					System.out.println("i  ::" + "j  ::" + arr[k][j][i]);
				}
			}
		}
		return timecubeobj;
	}

	public static MMASpaceCube readSpaceCube(String path, String filename) {
		validate("spacecube", path, filename);

		System.out.println("Initialise Spacecube array called" + X + ":::" + Y
				+ ":::" + Z);
		float arr[][][] = new float[Z][Y][X];
		String thisLine = "";
		int i = 0;
		int j = 0;
		int openfile = 0;

		for (int k = 0; k < Z; k++) {
			openfile = k + 1;
			String file1 = new String(path + openfile + ".dat");
			try {
				FileInputStream fis = new FileInputStream(file1);
				BufferedInputStream bis = new BufferedInputStream(fis);
				BufferedReader myInput = new BufferedReader(
						new InputStreamReader(bis));
				while ((thisLine = myInput.readLine()) != null) {
					// scan it line by line
					System.out.println(thisLine);
					StringTokenizer st = new StringTokenizer(thisLine);
					i = 0;
					while (st.hasMoreTokens()) {
						arr[k][j][i] = Float.valueOf(st.nextToken())
								.floatValue();
						// System.out.println(k+ "::" +j + "::" + i + "::" +
						// arr[k][j][i]);
						i++;
					}
					j++;
				}// end of while
				j = 0;
				fis.close();
				bis.close();
				myInput.close();
			} catch (Exception e) {
				System.out.println("Exception thrown from initialiseGridArray"
						+ e);
			}

			System.out.println("XX" + X);
			System.out.println("YY" + Y);
			System.out.println("ZZ" + Z);
		}

		MMASpaceCube spacecubeobj = new MMASpaceCube();
		spacecubeobj.putX(X);
		spacecubeobj.putY(Y);
		spacecubeobj.putZ(Z);
		spacecubeobj.putXResolution(xResolution);
		spacecubeobj.putYResolution(yResolution);
		spacecubeobj.putZResolution(zResolution);
		spacecubeobj.putNoData(noData);
		spacecubeobj.putData(arr);
		spacecubeobj.putXLL(xll);
		spacecubeobj.putYLL(yll);

		for (int k = 0; k < Z; k++) {
			for (j = 0; j < Y; j++) {
				for (i = 0; i < X; i++) {
					System.out.print("");
				}
			}
		}
		// System.out.println("i  ::"+"j  ::"+arr[k][j][i]);
		return spacecubeobj;
	}

	public static MMAHyperCube readHyperCube(String path, String filename) {
		validate("hypercube", path, filename);
		System.out.println("Initialise Hypercube array called" + X + ":::" + Y
				+ ":::" + Z + ":::" + T);
		float arr[][][][] = new float[T][Z][Y][X];
		String thisLine = "";
		int i = 0;
		int j = 0;
		int filecount = 0;
		int nooffiles = T * Z;

		for (int l = 0; l < T; l++) {
			for (int k = 0; k < Z; k++) {
				++filecount;
				String file1 = new String(path + filecount + ".dat");
				try {
					FileInputStream fis = new FileInputStream(file1);
					BufferedInputStream bis = new BufferedInputStream(fis);
					BufferedReader myInput = new BufferedReader(
							new InputStreamReader(bis));
					while ((thisLine = myInput.readLine()) != null) {
						// scan it line by line
						System.out.println(thisLine);
						StringTokenizer st = new StringTokenizer(thisLine);
						while (st.hasMoreTokens()) {
							arr[l][k][j][i] = Float.valueOf(st.nextToken())
									.floatValue();
							// System.out.println(l+"::::" +k+ "::" +j+ "::" + i
							// + "::" + arr[l][k][j][i]);
							i++;
						}
						j++;
						i = 0;
					}// end of while
					i = 0;
					j = 0;
					fis.close();
					bis.close();
					myInput.close();
				} catch (Exception e) {
					System.out
							.println("Exception thrown from initialiseGridArray"
									+ e);
				}
				System.out.println("XX" + X);
				System.out.println("YY" + Y);
				System.out.println("ZZ" + Z);
				System.out.println("TT" + T);
			}// end of for
		}

		MMAHyperCube hypercubeobj = new MMAHyperCube();
		hypercubeobj.putX(X);
		hypercubeobj.putY(Y);
		hypercubeobj.putZ(Z);
		hypercubeobj.putT(T);
		hypercubeobj.putXResolution(xResolution);
		hypercubeobj.putYResolution(yResolution);
		hypercubeobj.putZResolution(zResolution);
		hypercubeobj.putTResolution(tResolution);
		hypercubeobj.putNoData(noData);
		hypercubeobj.putData(arr);
		hypercubeobj.putXLL(xll);
		hypercubeobj.putYLL(yll);

		for (int l = 0; l < T; l++) {
			for (int k = 0; k < Z; k++) {
				for (j = 0; j < Y; j++) {
					for (i = 0; i < X; i++) {
						System.out.print("");
					}
				}
			}
		}
		// System.out.println(l+" ::"+k + "  ::  "+ j +"  ::  "+i +
		// "  ::::::"+arr[l][k][j][i]);
		return hypercubeobj;
	} // end of MMAHypercube

	public static MMATimeSeries readTimeSeries(String path, String filename) {
		validate("timeseries", path, filename);
		System.out.println("Initialise Timeseries array called" + X + ":::" + Y
				+ ":::" + T);
		float arr[] = new float[T];
		String thisLine = "";
		int i = 0;
		int j = 0;
		String file1 = new String(path + "1.dat");
		try {
			FileInputStream fis = new FileInputStream(file1);
			BufferedInputStream bis = new BufferedInputStream(fis);
			BufferedReader myInput = new BufferedReader(new InputStreamReader(
					bis));
			while ((thisLine = myInput.readLine()) != null) {
				// scan it line by line
				System.out.print(thisLine);
				StringTokenizer st = new StringTokenizer(thisLine);
				while (st.hasMoreTokens()) {
					arr[i] = Float.valueOf(st.nextToken()).floatValue();
					System.out.println("::arr[" + i + "]::" + arr[i]);
					i++;
				}
			}// end of while
			fis.close();
			bis.close();
			myInput.close();
		} catch (Exception e) {
			System.out.println("Exception thrown from initialiseGridArray" + e);
		}

		System.out.println("XX" + X);
		System.out.println("YY" + Y);
		System.out.println("ZZ" + T);
		MMATimeSeries tsobj = new MMATimeSeries();

		tsobj.putT(T);
		tsobj.putTResolution(tResolution);
		tsobj.putData(arr);
		tsobj.putNoData(noData);
		tsobj.putXLL(xll);
		tsobj.putYLL(yll);

		for (i = 0; i < arr.length; i++) {
			System.out.println("i  ::" + "j  ::" + arr[i]);
		}

		return tsobj;
	}// end of method readTimeSeries

}// end of class
